package cn.tlb.gl.game.model;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.opengl.Matrix;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import cn.tlb.xutilsdownload.R;

/**
 * Created by 汤林冰 on 2016/1/12 11:45.
 */
public class ModelRenderer implements GLSurfaceView.Renderer{

        /**人物头部尺寸, 以此作为标准, 头像纹理占8个像素,取值为1,由此计算比例*/
        private static final float HEAD_SIZE = .5f;
        private static final float unit = HEAD_SIZE/8;

        // body 8*4*12
        private static final float body_length = 4*unit;//长
        private static final float body_width = 2*unit;//宽
        private static final float body_height = 6*unit;//高
        private static final float body_x = 0;
        private static final float body_y = 0;
        private static final float head = HEAD_SIZE/2;
        // 帽子和头部间距0.5像素
        private static final float cap_space = unit/2;

        ///////////////////////////////////////////////////////////////////////////
        // 人物头部
        ///////////////////////////////////////////////////////////////////////////
        private static final float head_x = body_x;
        private static final float head_y = body_y + body_height + head;
        FloatBuffer head_top = array2FloatBuffer(new float[]{
                head_x - head, head_y + head, -head,
                head_x - head, head_y + head, head,
                head_x + head, head_y + head, -head,
                head_x - head, head_y + head, head,
                head_x + head, head_y + head, -head,
                head_x + head, head_y + head, head,
        });

        FloatBuffer head_bottom = array2FloatBuffer(new float[]{
                head_x - head, head_y - head, -head,
                head_x - head, head_y - head, head,
                head_x + head, head_y - head, -head,
                head_x - head, head_y - head, head,
                head_x + head, head_y - head, -head,
                head_x + head, head_y - head, head,
        });

        FloatBuffer head_left = array2FloatBuffer(new float[]{
                head_x - head, head_y + head, -head,
                head_x - head, head_y - head, -head,
                head_x - head, head_y + head, head,
                head_x - head, head_y - head, -head,
                head_x - head, head_y + head, head,
                head_x - head, head_y - head, head,
        });

        FloatBuffer head_right = array2FloatBuffer(new float[]{
                head_x + head, head_y + head, -head,
                head_x + head, head_y - head, -head,
                head_x + head, head_y + head, head,
                head_x + head, head_y - head, -head,
                head_x + head, head_y + head, head,
                head_x + head, head_y - head, head,
        });

        FloatBuffer head_front = array2FloatBuffer(new float[]{
                head_x - head, head_y + head, head,
                head_x - head, head_y - head, head,
                head_x + head, head_y + head, head,
                head_x - head, head_y - head, head,
                head_x + head, head_y + head, head,
                head_x + head, head_y - head, head,
        });

        FloatBuffer head_back = array2FloatBuffer(new float[]{
                head_x - head, head_y + head, -head,
                head_x - head, head_y - head, -head,
                head_x + head, head_y + head, -head,
                head_x - head, head_y - head, -head,
                head_x + head, head_y + head, -head,
                head_x + head, head_y - head, -head,
        });

        ///////////////////////////////////////////////////////////////////////////
        // 人物帽子
        ///////////////////////////////////////////////////////////////////////////
        private static final float cap = head+cap_space;
        private static final float cap_x = head_x;
        private static final float cap_y = head_y;
        FloatBuffer cap_top = array2FloatBuffer(new float[]{
                cap_x - cap, cap_y + cap, -cap,
                cap_x - cap, cap_y + cap, cap,
                cap_x + cap, cap_y + cap, -cap,
                cap_x - cap, cap_y + cap, cap,
                cap_x + cap, cap_y + cap, -cap,
                cap_x + cap, cap_y + cap, cap,
        });

        FloatBuffer cap_bottom = array2FloatBuffer(new float[]{
                cap_x - cap, cap_y - cap, -cap,
                cap_x - cap, cap_y - cap, cap,
                cap_x + cap, cap_y - cap, -cap,
                cap_x - cap, cap_y - cap, cap,
                cap_x + cap, cap_y - cap, -cap,
                cap_x + cap, cap_y - cap, cap,
        });

        FloatBuffer cap_left = array2FloatBuffer(new float[]{
                cap_x - cap, cap_y + cap, -cap,
                cap_x - cap, cap_y - cap, -cap,
                cap_x - cap, cap_y + cap, cap,
                cap_x - cap, cap_y - cap, -cap,
                cap_x - cap, cap_y + cap, cap,
                cap_x - cap, cap_y - cap, cap,
        });

        FloatBuffer cap_right = array2FloatBuffer(new float[]{
                cap_x + cap, cap_y + cap, -cap,
                cap_x + cap, cap_y - cap, -cap,
                cap_x + cap, cap_y + cap, cap,
                cap_x + cap, cap_y - cap, -cap,
                cap_x + cap, cap_y + cap, cap,
                cap_x + cap, cap_y - cap, cap,
        });

        FloatBuffer cap_front = array2FloatBuffer(new float[]{
                cap_x - cap, cap_y + cap, cap,
                cap_x - cap, cap_y - cap, cap,
                cap_x + cap, cap_y + cap, cap,
                cap_x - cap, cap_y - cap, cap,
                cap_x + cap, cap_y + cap, cap,
                cap_x + cap, cap_y - cap, cap,
        });

        FloatBuffer cap_back = array2FloatBuffer(new float[]{
                cap_x - cap, cap_y + cap, -cap,
                cap_x - cap, cap_y - cap, -cap,
                cap_x + cap, cap_y + cap, -cap,
                cap_x - cap, cap_y - cap, -cap,
                cap_x + cap, cap_y + cap, -cap,
                cap_x + cap, cap_y - cap, -cap,
        });
        ///////////////////////////////////////////////////////////////////////////
        // arm
        ///////////////////////////////////////////////////////////////////////////
        private static final float arm = body_width;
        private static final float arm_length = body_height;
        private static final float left_arm_x = body_x - body_length - arm;
        private static final float left_arm_y = body_y;

        FloatBuffer left_arm_top = array2FloatBuffer(new float[]{
                left_arm_x - arm, left_arm_y + arm_length, -arm,
                left_arm_x - arm, left_arm_y + arm_length, arm,
                left_arm_x + arm, left_arm_y + arm_length, -arm,
                left_arm_x - arm, left_arm_y + arm_length, arm,
                left_arm_x + arm, left_arm_y + arm_length, -arm,
                left_arm_x + arm, left_arm_y + arm_length, arm,
        });

        FloatBuffer left_arm_bottom = array2FloatBuffer(new float[]{
                left_arm_x - arm, left_arm_y - arm_length, -arm,
                left_arm_x - arm, left_arm_y - arm_length, arm,
                left_arm_x + arm, left_arm_y - arm_length, -arm,
                left_arm_x - arm, left_arm_y - arm_length, arm,
                left_arm_x + arm, left_arm_y - arm_length, -arm,
                left_arm_x + arm, left_arm_y - arm_length, arm,
        });

        FloatBuffer left_arm_left = array2FloatBuffer(new float[]{
                left_arm_x - arm, left_arm_y + arm_length, -arm,
                left_arm_x - arm, left_arm_y - arm_length, -arm,
                left_arm_x - arm, left_arm_y + arm_length, arm,
                left_arm_x - arm, left_arm_y - arm_length, -arm,
                left_arm_x - arm, left_arm_y + arm_length, arm,
                left_arm_x - arm, left_arm_y - arm_length, arm,
        });

        FloatBuffer left_arm_right = array2FloatBuffer(new float[]{
                left_arm_x + arm, left_arm_y + arm_length, -arm,
                left_arm_x + arm, left_arm_y - arm_length, -arm,
                left_arm_x + arm, left_arm_y + arm_length, arm,
                left_arm_x + arm, left_arm_y - arm_length, -arm,
                left_arm_x + arm, left_arm_y + arm_length, arm,
                left_arm_x + arm, left_arm_y - arm_length, arm,
        });

        FloatBuffer left_arm_front = array2FloatBuffer(new float[]{
                left_arm_x - arm, left_arm_y + arm_length, arm,
                left_arm_x - arm, left_arm_y - arm_length, arm,
                left_arm_x + arm, left_arm_y + arm_length, arm,
                left_arm_x - arm, left_arm_y - arm_length, arm,
                left_arm_x + arm, left_arm_y + arm_length, arm,
                left_arm_x + arm, left_arm_y - arm_length, arm,
        });

        FloatBuffer left_arm_back = array2FloatBuffer(new float[]{
                left_arm_x - arm, left_arm_y + arm_length, -arm,
                left_arm_x - arm, left_arm_y - arm_length, -arm,
                left_arm_x + arm, left_arm_y + arm_length, -arm,
                left_arm_x - arm, left_arm_y - arm_length, -arm,
                left_arm_x + arm, left_arm_y + arm_length, -arm,
                left_arm_x + arm, left_arm_y - arm_length, -arm,
        });

        private static final float right_arm_x = -left_arm_x;
        private static final float right_arm_y = left_arm_y;
        // left -> right
        FloatBuffer right_arm_top = array2FloatBuffer(new float[]{
                right_arm_x - arm, right_arm_y + arm_length, -arm,
                right_arm_x - arm, right_arm_y + arm_length, arm,
                right_arm_x + arm, right_arm_y + arm_length, -arm,
                right_arm_x - arm, right_arm_y + arm_length, arm,
                right_arm_x + arm, right_arm_y + arm_length, -arm,
                right_arm_x + arm, right_arm_y + arm_length, arm,
        });

        FloatBuffer right_arm_bottom = array2FloatBuffer(new float[]{
                right_arm_x - arm, right_arm_y - arm_length, -arm,
                right_arm_x - arm, right_arm_y - arm_length, arm,
                right_arm_x + arm, right_arm_y - arm_length, -arm,
                right_arm_x - arm, right_arm_y - arm_length, arm,
                right_arm_x + arm, right_arm_y - arm_length, -arm,
                right_arm_x + arm, right_arm_y - arm_length, arm,
        });

        FloatBuffer right_arm_left = array2FloatBuffer(new float[]{
                right_arm_x - arm, right_arm_y + arm_length, -arm,
                right_arm_x - arm, right_arm_y - arm_length, -arm,
                right_arm_x - arm, right_arm_y + arm_length, arm,
                right_arm_x - arm, right_arm_y - arm_length, -arm,
                right_arm_x - arm, right_arm_y + arm_length, arm,
                right_arm_x - arm, right_arm_y - arm_length, arm,
        });

        FloatBuffer right_arm_right = array2FloatBuffer(new float[]{
                right_arm_x + arm, right_arm_y + arm_length, -arm,
                right_arm_x + arm, right_arm_y - arm_length, -arm,
                right_arm_x + arm, right_arm_y + arm_length, arm,
                right_arm_x + arm, right_arm_y - arm_length, -arm,
                right_arm_x + arm, right_arm_y + arm_length, arm,
                right_arm_x + arm, right_arm_y - arm_length, arm,
        });

        FloatBuffer right_arm_front = array2FloatBuffer(new float[]{
                right_arm_x - arm, right_arm_y + arm_length, arm,
                right_arm_x - arm, right_arm_y - arm_length, arm,
                right_arm_x + arm, right_arm_y + arm_length, arm,
                right_arm_x - arm, right_arm_y - arm_length, arm,
                right_arm_x + arm, right_arm_y + arm_length, arm,
                right_arm_x + arm, right_arm_y - arm_length, arm,
        });

        FloatBuffer right_arm_back = array2FloatBuffer(new float[]{
                right_arm_x - arm, right_arm_y + arm_length, -arm,
                right_arm_x - arm, right_arm_y - arm_length, -arm,
                right_arm_x + arm, right_arm_y + arm_length, -arm,
                right_arm_x - arm, right_arm_y - arm_length, -arm,
                right_arm_x + arm, right_arm_y + arm_length, -arm,
                right_arm_x + arm, right_arm_y - arm_length, -arm,
        });

        ///////////////////////////////////////////////////////////////////////////
        // body
        ///////////////////////////////////////////////////////////////////////////

        FloatBuffer body_top = array2FloatBuffer(new float[]{
                body_x - body_length, body_y + body_height, -body_width,
                body_x - body_length, body_y + body_height, body_width,
                body_x + body_length, body_y + body_height, -body_width,
                body_x - body_length, body_y + body_height, body_width,
                body_x + body_length, body_y + body_height, -body_width,
                body_x + body_length, body_y + body_height, body_width,
        });

        FloatBuffer body_bottom = array2FloatBuffer(new float[]{
                body_x - body_length, body_y - body_height, -body_width,
                body_x - body_length, body_y - body_height, body_width,
                body_x + body_length, body_y - body_height, -body_width,
                body_x - body_length, body_y - body_height, body_width,
                body_x + body_length, body_y - body_height, -body_width,
                body_x + body_length, body_y - body_height, body_width,
        });

        FloatBuffer body_left = array2FloatBuffer(new float[]{
                body_x - body_length, body_y + body_height, -body_width,
                body_x - body_length, body_y - body_height, -body_width,
                body_x - body_length, body_y + body_height, body_width,
                body_x - body_length, body_y - body_height, -body_width,
                body_x - body_length, body_y + body_height, body_width,
                body_x - body_length, body_y - body_height, body_width,
        });

        FloatBuffer body_right = array2FloatBuffer(new float[]{
                body_x + body_length, body_y + body_height, -body_width,
                body_x + body_length, body_y - body_height, -body_width,
                body_x + body_length, body_y + body_height, body_width,
                body_x + body_length, body_y - body_height, -body_width,
                body_x + body_length, body_y + body_height, body_width,
                body_x + body_length, body_y - body_height, body_width,
        });

        FloatBuffer body_front = array2FloatBuffer(new float[]{
                body_x - body_length, body_y + body_height, body_width,
                body_x - body_length, body_y - body_height, body_width,
                body_x + body_length, body_y + body_height, body_width,
                body_x - body_length, body_y - body_height, body_width,
                body_x + body_length, body_y + body_height, body_width,
                body_x + body_length, body_y - body_height, body_width,
        });

        FloatBuffer body_back = array2FloatBuffer(new float[]{
                body_x - body_length, body_y + body_height, -body_width,
                body_x - body_length, body_y - body_height, -body_width,
                body_x + body_length, body_y + body_height, -body_width,
                body_x - body_length, body_y - body_height, -body_width,
                body_x + body_length, body_y + body_height, -body_width,
                body_x + body_length, body_y - body_height, -body_width,
        });

        ///////////////////////////////////////////////////////////////////////////
        // legs
        ///////////////////////////////////////////////////////////////////////////
        private static final float leg = body_width;
        private static final float leg_length = 3*leg;
        private static final float left_leg_x = body_x - leg;
        private static final float left_leg_y = body_y - body_height - leg_length;

        FloatBuffer left_leg_top = array2FloatBuffer(new float[]{
                left_leg_x - leg, left_leg_y + leg_length, -leg,
                left_leg_x - leg, left_leg_y + leg_length, leg,
                left_leg_x + leg, left_leg_y + leg_length, -leg,
                left_leg_x - leg, left_leg_y + leg_length, leg,
                left_leg_x + leg, left_leg_y + leg_length, -leg,
                left_leg_x + leg, left_leg_y + leg_length, leg,
        });

        FloatBuffer left_leg_bottom = array2FloatBuffer(new float[]{
                left_leg_x - leg, left_leg_y - leg_length, -leg,
                left_leg_x - leg, left_leg_y - leg_length, leg,
                left_leg_x + leg, left_leg_y - leg_length, -leg,
                left_leg_x - leg, left_leg_y - leg_length, leg,
                left_leg_x + leg, left_leg_y - leg_length, -leg,
                left_leg_x + leg, left_leg_y - leg_length, leg,
        });

        FloatBuffer left_leg_left = array2FloatBuffer(new float[]{
                left_leg_x - leg, left_leg_y + leg_length, -leg,
                left_leg_x - leg, left_leg_y - leg_length, -leg,
                left_leg_x - leg, left_leg_y + leg_length, leg,
                left_leg_x - leg, left_leg_y - leg_length, -leg,
                left_leg_x - leg, left_leg_y + leg_length, leg,
                left_leg_x - leg, left_leg_y - leg_length, leg,
        });

        FloatBuffer left_leg_right = array2FloatBuffer(new float[]{
                left_leg_x + leg, left_leg_y + leg_length, -leg,
                left_leg_x + leg, left_leg_y - leg_length, -leg,
                left_leg_x + leg, left_leg_y + leg_length, leg,
                left_leg_x + leg, left_leg_y - leg_length, -leg,
                left_leg_x + leg, left_leg_y + leg_length, leg,
                left_leg_x + leg, left_leg_y - leg_length, leg,
        });

        FloatBuffer left_leg_front = array2FloatBuffer(new float[]{
                left_leg_x - leg, left_leg_y + leg_length, leg,
                left_leg_x - leg, left_leg_y - leg_length, leg,
                left_leg_x + leg, left_leg_y + leg_length, leg,
                left_leg_x - leg, left_leg_y - leg_length, leg,
                left_leg_x + leg, left_leg_y + leg_length, leg,
                left_leg_x + leg, left_leg_y - leg_length, leg,
        });

        FloatBuffer left_leg_back = array2FloatBuffer(new float[]{
                left_leg_x - leg, left_leg_y + leg_length, -leg,
                left_leg_x - leg, left_leg_y - leg_length, -leg,
                left_leg_x + leg, left_leg_y + leg_length, -leg,
                left_leg_x - leg, left_leg_y - leg_length, -leg,
                left_leg_x + leg, left_leg_y + leg_length, -leg,
                left_leg_x + leg, left_leg_y - leg_length, -leg,
        });

        private static final float right_leg_x = -left_leg_x;
        private static final float right_leg_y = left_leg_y;
        // left -> right
        FloatBuffer right_leg_top = array2FloatBuffer(new float[]{
                right_leg_x - leg, right_leg_y + leg_length, -leg,
                right_leg_x - leg, right_leg_y + leg_length, leg,
                right_leg_x + leg, right_leg_y + leg_length, -leg,
                right_leg_x - leg, right_leg_y + leg_length, leg,
                right_leg_x + leg, right_leg_y + leg_length, -leg,
                right_leg_x + leg, right_leg_y + leg_length, leg,
        });

        FloatBuffer right_leg_bottom = array2FloatBuffer(new float[]{
                right_leg_x - leg, right_leg_y - leg_length, -leg,
                right_leg_x - leg, right_leg_y - leg_length, leg,
                right_leg_x + leg, right_leg_y - leg_length, -leg,
                right_leg_x - leg, right_leg_y - leg_length, leg,
                right_leg_x + leg, right_leg_y - leg_length, -leg,
                right_leg_x + leg, right_leg_y - leg_length, leg,
        });

        FloatBuffer right_leg_left = array2FloatBuffer(new float[]{
                right_leg_x - leg, right_leg_y + leg_length, -leg,
                right_leg_x - leg, right_leg_y - leg_length, -leg,
                right_leg_x - leg, right_leg_y + leg_length, leg,
                right_leg_x - leg, right_leg_y - leg_length, -leg,
                right_leg_x - leg, right_leg_y + leg_length, leg,
                right_leg_x - leg, right_leg_y - leg_length, leg,
        });

        FloatBuffer right_leg_right = array2FloatBuffer(new float[]{
                right_leg_x + leg, right_leg_y + leg_length, -leg,
                right_leg_x + leg, right_leg_y - leg_length, -leg,
                right_leg_x + leg, right_leg_y + leg_length, leg,
                right_leg_x + leg, right_leg_y - leg_length, -leg,
                right_leg_x + leg, right_leg_y + leg_length, leg,
                right_leg_x + leg, right_leg_y - leg_length, leg,
        });

        FloatBuffer right_leg_front = array2FloatBuffer(new float[]{
                right_leg_x - leg, right_leg_y + leg_length, leg,
                right_leg_x - leg, right_leg_y - leg_length, leg,
                right_leg_x + leg, right_leg_y + leg_length, leg,
                right_leg_x - leg, right_leg_y - leg_length, leg,
                right_leg_x + leg, right_leg_y + leg_length, leg,
                right_leg_x + leg, right_leg_y - leg_length, leg,
        });

        FloatBuffer right_leg_back = array2FloatBuffer(new float[]{
                right_leg_x - leg, right_leg_y + leg_length, -leg,
                right_leg_x - leg, right_leg_y - leg_length, -leg,
                right_leg_x + leg, right_leg_y + leg_length, -leg,
                right_leg_x - leg, right_leg_y - leg_length, -leg,
                right_leg_x + leg, right_leg_y + leg_length, -leg,
                right_leg_x + leg, right_leg_y - leg_length, -leg,
        });


        //顶点index
        ByteBuffer indexBuffer = ByteBuffer.wrap(new byte[]{0, 1, 2, 3, 4, 5});

        //纹理坐标
        FloatBuffer textBuffer = array2FloatBuffer(new float[]{
                0,0,    0,1,    1,0,
                0,1,    1,0,    1,1
        });
    private float mAngleX;
    private float mAngleY;
    private Resources resources;
    public ModelRenderer(Context context){
        resources = context.getResources();
    }

    public void setAngleX(float angleX) {
        this.mAngleX = angleX;
    }

    public void setAngleY(float angleY) {
        this.mAngleY = angleY;
    }

    @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            gl.glDisable(GL10.GL_DITHER);
            gl.glShadeModel(GL10.GL_SMOOTH);

            gl.glClearColor(0.0f, 0.0f, 0.0f, 0.3f);
            gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
            gl.glEnable(GL10.GL_DEPTH_TEST);
            gl.glDepthFunc(GL10.GL_LEQUAL);

            //启用2d纹理贴图
            gl.glEnable(GL10.GL_TEXTURE_2D);
            loadTexture(gl);

            //启用opengl混合, 详见 http://dxwang.blog.51cto.com/384651/693834
            gl.glEnable(GL10.GL_BLEND);
            gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
        }

        private static final int index_head_top = 0;
        private static final int index_head_front = 1;
        private static final int index_head_left = 2;
        private static final int index_head_right = 3;
        private static final int index_head_back = 4;
        private static final int index_head_bottom = 5;
        private static final int index_cap_top = 6;
        private static final int index_cap_front = 7;
        private static final int index_cap_left = 8;
        private static final int index_cap_right = 9;
        private static final int index_cap_back = 10;
        private static final int index_cap_bottom = 11;
        private static final int index_left_arm_top = 12;
        private static final int index_left_arm_front = 13;
        private static final int index_left_arm_left = 14;
        private static final int index_left_arm_right = 15;
        private static final int index_left_arm_back = 16;
        private static final int index_left_arm_bottom = 17;
        private static final int index_body_top = 18;
        private static final int index_body_front = 19;
        private static final int index_body_left = 20;
        private static final int index_body_right = 21;
        private static final int index_body_back = 22;
        private static final int index_body_bottom = 23;
        private static final int index_left_leg_top = 24;
        private static final int index_left_leg_front = 25;
        private static final int index_left_leg_left = 26;
        private static final int index_left_leg_right = 27;
        private static final int index_left_leg_back = 28;
        private static final int index_left_leg_bottom = 29;
        int[] ids = {
                R.drawable.head_top, R.drawable.head_front,R.drawable.head_left,
                R.drawable.head_right,R.drawable.head_back,R.drawable.head_bottom,
                R.drawable.cap_top, R.drawable.cap_front, R.drawable.cap_left,
                R.drawable.cap_right,R.drawable.cap_back,R.drawable.cap_bottom,
                R.drawable.left_arm_top, R.drawable.left_arm_front, R.drawable.left_arm_left,
                R.drawable.left_arm_right,R.drawable.left_arm_back,R.drawable.left_arm_bottom,
                R.drawable.body_top, R.drawable.body_front,R.drawable.body_left,
                R.drawable.body_right,R.drawable.body_back,R.drawable.body_bottom,
                R.drawable.left_leg_top, R.drawable.left_leg_front, R.drawable.left_leg_left,
                R.drawable.left_leg_right,R.drawable.left_leg_back,R.drawable.left_leg_bottom,
        };
        int[] textures = new int[ids.length];

    private void loadTexture(GL10 gl) {
        gl.glGenTextures(textures.length, textures, 0);
        for (int i = 0; i < textures.length; i++) {
            Bitmap bitmap = BitmapFactory.decodeResource(resources, ids[i]);
            //在为纹理提供图像数据之前，我们必须绑定纹理
            gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[i]);
            gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
            // TODO 此处原设为 GL_LINEAR 然游戏图片中显示为像素点即可,也就是不使用插值, 因而选用 GL_NEAREST
            gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
            gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
            gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
            GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

            bitmap.recycle();
            bitmap = null;
        }
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glViewport(0, 0, width, height);
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        float ratio = (float)width/height;
        float y = 1;
        gl.glFrustumf(-ratio*y, ratio*y, -y, y, 1, 20);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_DEPTH_BUFFER_BIT | GL10.GL_COLOR_BUFFER_BIT);
        gl.glMatrixMode(GL10.GL_MODELVIEW);

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        drawBody(gl, body_top, textures[index_body_top]);
        drawBody(gl, body_bottom, textures[index_body_bottom]);
        drawBody(gl, body_left, textures[index_body_left]);
        drawBody(gl, body_right, textures[index_body_right]);
        drawBody(gl, body_front, textures[index_body_front]);
        drawBody(gl, body_back, textures[index_body_back]);

        drawFace(gl, head_top, textures[index_head_top]);
        drawFace(gl, head_bottom, textures[index_head_bottom]);
        drawFace(gl, head_left, textures[index_head_left]);
        drawFace(gl, head_right, textures[index_head_right]);
        drawFace(gl, head_front, textures[index_head_front]);
        drawFace(gl, head_back, textures[index_head_back]);

        drawFace(gl, cap_top, textures[index_cap_top]);
        drawFace(gl, cap_bottom, textures[index_cap_bottom]);
        drawFace(gl, cap_left, textures[index_cap_left]);
        drawFace(gl, cap_right, textures[index_cap_right]);
        drawFace(gl, cap_front, textures[index_cap_front]);
        drawFace(gl, cap_back, textures[index_cap_back]);

        drawLeftArm(gl, left_arm_top, textures[index_left_arm_top]);
        drawLeftArm(gl, left_arm_bottom, textures[index_left_arm_bottom]);
        drawLeftArm(gl, left_arm_left, textures[index_left_arm_left]);
        drawLeftArm(gl, left_arm_right, textures[index_left_arm_right]);
        drawLeftArm(gl, left_arm_front, textures[index_left_arm_front]);
        drawLeftArm(gl, left_arm_back, textures[index_left_arm_back]);

        drawRightArm(gl, right_arm_top, textures[index_left_arm_top]);
        drawRightArm(gl, right_arm_bottom, textures[index_left_arm_bottom]);
        drawRightArm(gl, right_arm_left, textures[index_left_arm_left]);
        drawRightArm(gl, right_arm_right, textures[index_left_arm_right]);
        drawRightArm(gl, right_arm_front, textures[index_left_arm_front]);
        drawRightArm(gl, right_arm_back, textures[index_left_arm_back]);

        drawLeftLeg(gl, left_leg_top, textures[index_left_leg_top]);
        drawLeftLeg(gl, left_leg_bottom, textures[index_left_leg_bottom]);
        drawLeftLeg(gl, left_leg_left, textures[index_left_leg_left]);
        drawLeftLeg(gl, left_leg_right, textures[index_left_leg_right]);
        drawLeftLeg(gl, left_leg_front, textures[index_left_leg_front]);
        drawLeftLeg(gl, left_leg_back, textures[index_left_leg_back]);

        drawRightLeg(gl, right_leg_top, textures[index_left_leg_top]);
        drawRightLeg(gl, right_leg_bottom, textures[index_left_leg_bottom]);
        drawRightLeg(gl, right_leg_left, textures[index_left_leg_left]);
        drawRightLeg(gl, right_leg_right, textures[index_left_leg_right]);
        drawRightLeg(gl, right_leg_front, textures[index_left_leg_front]);
        drawRightLeg(gl, right_leg_back, textures[index_left_leg_back]);

        gl.glFinish();
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        head_rotate_x += 0.2;
        head_rotate_y += 0.1;
        arm_rotate_x += 1;
        arm_rotate_y -=1;
    }

    private float[] m = new float[16];
    private void drawFace(GL10 gl, FloatBuffer vertex, int textureID) {
        gl.glLoadIdentity();
        // TODO 注意:矩阵变换的执行顺序从下往上,也就是栈的存储方式
        Matrix.setIdentityM(m, 0);
        Matrix.translateM(m, 0, 0, 0, -2);//最后按向量(0, 0, -2)平移
        Matrix.rotateM(m, 0, mAngleX, 0, 1, 0);
        Matrix.rotateM(m, 0, mAngleY, 1, 0, 0);
        Matrix.translateM(m, 0, 0, head + body_height, 0);
        Matrix.rotateM(m, 0, f(head_rotate_x), 1, 0, 0);
        Matrix.translateM(m, 0, 0, -(head + body_height), 0);
        Matrix.rotateM(m, 0, f(head_rotate_y), 0, 1, 0);
        gl.glLoadMatrixf(m, 0);

        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textBuffer);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
        gl.glDrawElements(GL10.GL_TRIANGLES, indexBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, indexBuffer);
    }

    private void drawLeftArm(GL10 gl, FloatBuffer vertex, int textureID) {
        gl.glLoadIdentity();
        Matrix.setIdentityM(m, 0);
        Matrix.translateM(m, 0, 0, 0, -2);
        Matrix.rotateM(m, 0, mAngleX, 0, 1, 0);
        Matrix.rotateM(m, 0, mAngleY, 1, 0, 0);
        Matrix.translateM(m, 0, 0, arm_length / 2, 0);
        Matrix.rotateM(m, 0, g(arm_rotate_x), 1, 0, 0);
        Matrix.translateM(m, 0, 0, -arm_length / 2, 0);
        gl.glLoadMatrixf(m, 0);

        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textBuffer);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
        gl.glDrawElements(GL10.GL_TRIANGLES, indexBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, indexBuffer);
    }

    private void drawRightArm(GL10 gl, FloatBuffer vertex, int textureID) {
        gl.glLoadIdentity();
        Matrix.setIdentityM(m, 0);
        Matrix.translateM(m, 0, 0, 0, -2);
        Matrix.rotateM(m, 0, mAngleX, 0, 1, 0);
        Matrix.rotateM(m, 0, mAngleY, 1, 0, 0);
        Matrix.translateM(m, 0, 0, arm_length / 2, 0);
        Matrix.rotateM(m, 0, -g(arm_rotate_x), 1, 0, 0);
        Matrix.translateM(m, 0, 0, -arm_length / 2, 0);
        gl.glLoadMatrixf(m, 0);

        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textBuffer);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
        gl.glDrawElements(GL10.GL_TRIANGLES, indexBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, indexBuffer);
    }

    private void drawBody(GL10 gl, FloatBuffer vertex, int textureID) {
        gl.glLoadIdentity();
        Matrix.setIdentityM(m, 0);
        Matrix.translateM(m, 0, 0, 0, -2);
        Matrix.rotateM(m, 0, mAngleX, 0, 1, 0);
        Matrix.rotateM(m, 0, mAngleY, 1, 0, 0);
        gl.glLoadMatrixf(m, 0);

        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textBuffer);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
        gl.glDrawElements(GL10.GL_TRIANGLES, indexBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, indexBuffer);
    }

    private void drawLeftLeg(GL10 gl, FloatBuffer vertex, int textureID) {
        gl.glLoadIdentity();
        gl.glTranslatef(0, 0, -2);
        gl.glRotatef(mAngleX, 0, 1, 0);
        gl.glRotatef(mAngleY, 1, 0, 0);
        gl.glTranslatef(0, -body_height, 0);
        gl.glRotatef(-g(arm_rotate_x), 1, 0, 0);
        gl.glTranslatef(0, body_height, 0);

        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textBuffer);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
        gl.glDrawElements(GL10.GL_TRIANGLES, indexBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, indexBuffer);

    }

    private void drawRightLeg(GL10 gl, FloatBuffer vertex, int textureID) {
        gl.glLoadIdentity();
        gl.glTranslatef(0, 0, -2);
        gl.glRotatef(mAngleX, 0, 1, 0);
        gl.glRotatef(mAngleY, 1, 0, 0);
        gl.glTranslatef(0, -body_height, 0);
        gl.glRotatef(g(arm_rotate_x), 1, 0, 0);
        gl.glTranslatef(0, body_height, 0);

        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textBuffer);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
        gl.glDrawElements(GL10.GL_TRIANGLES, indexBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, indexBuffer);

    }

    private float head_rotate_x;
    private float head_rotate_y;
    //头部扭动
    private float f(float x){
        x = x%40 - 10;// [-10, 30], 周期40
        // 函数 f(x) = -|x| 右移10,上移10
        return -Math.abs(x-10)+10;
    }

    private float arm_rotate_x;
    private float arm_rotate_y;
    // 四肢的摆动函数
    private float g(float x){
        x = x%80 - 20;
        return -Math.abs(x-20)+20;
    }

    protected FloatBuffer array2FloatBuffer(float fs[]){
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(fs.length * 4);
        byteBuffer.order(ByteOrder.nativeOrder());
        FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
        floatBuffer.put(fs);
        floatBuffer.position(0);
        return floatBuffer;
    }

    protected IntBuffer array2IntBuffer(int ints[]){
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(ints.length * 4);
        byteBuffer.order(ByteOrder.nativeOrder());
        IntBuffer intBuffer = byteBuffer.asIntBuffer();
        intBuffer.put(ints);
        intBuffer.position(0);
        return intBuffer;
    }

}
